package com.longtop.framework.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.longtop.framework.sys.auth.service.AuthOperService;
import com.longtop.framework.sys.codeInfo.model.TSysCodeInfo;
import com.longtop.framework.sys.codeInfo.service.CodeInfoService;
import com.longtop.framework.sys.config.model.TSysConfig;
import com.longtop.framework.sys.config.service.ConfigService;
import com.longtop.framework.sys.org.model.TSysOrg;
import com.longtop.framework.sys.org.service.OrgService;
import com.longtop.framework.util.SpringBeanFactory;

/**
 * 基础数据管理类。<br>
 * <p/> 在服务器启动时，自动把菜单表、代码表等基础数据装载到内存中，以加快访问速度<br>
 * <p/> 该类由BaseDataListener调用 <p/>
 * 
 * @author 胡砥峰
 * @version 2.0
 */
public class BaseDataManage {

	/**
	 * 缓存001：（代码信息TIO_SYS_CODE_INFO）codeInfoMap< codeTypeId, List<SysCodeInfo> >
	 */
	private static Map<String, List<TSysCodeInfo>> codeInfoMap = null;

	/**
	 * 缓存002：（角色对菜单的操作权限TIO_SYS_AUTH_OPER）authOperMenuMap< roleId, List<operId> >
	 */
	private static Map<String, List<String>> authOperMenuMap = null;

	/**
	 * 缓存002：（角色对功能的操作权限TIO_SYS_AUTH_OPER）authOperFuncMap< roleId, List<operId> >
	 */
	private static Map<String, List<String>> authOperFuncMap = null;

	/**
	 * 缓存003：（机构TIO_SYS_ORG）orgMap< id, SysOrg >
	 */
	private static Map<String, TSysOrg> orgMap = null;

	/**
	 * 缓存004：缓存 机构id及其的子机构id列表 allSubOrgMap< orgId, list<orgId> >
	 */
	private static Map<String, List<String>> allSubOrgMap = null;

	/**
	 * 缓存005：缓存 参数config<Id, Config> 数据
	 */
	private static Map<String, TSysConfig> configMap = null;

	/**
	 * 该方法由BaseDataListener在contextInitialized时调用。
	 */
	public static void init() {
		codeInfoMap = null;
		authOperMenuMap = null;
		authOperFuncMap = null;
		orgMap = null;
		allSubOrgMap = null;
		configMap = null;
		
		// 装载基础数据到内存
		loadCodeInfoMap();
		loadAuthOperMap();
		loadOrgMap();
		loadAllSubOrgMap();
		loadConfigMap();
	}

	/**
	 * 该方法由BaseDataListener在 监听器停止 时调用。
	 */
	public static void destroy() {
		codeInfoMap = null;
		authOperMenuMap = null;
		authOperFuncMap = null;
		orgMap = null;
		allSubOrgMap = null;
		configMap = null;
	}

	/**
	 * 装载->缓存001：（代码信息TIO_SYS_CODE_INFO）codeInfoMap< codeTypeId, List<SysCodeInfo> >
	 */
	private static void loadCodeInfoMap() {
		// 1)把代码表数据装入内存（按码种分类）
		if (codeInfoMap == null) {
			CodeInfoService codeInfoService = SpringBeanFactory.getBean(CodeInfoService.BEAN_ID);
			codeInfoMap = codeInfoService.getCodeInfoMap(null);
		}
	}

	public static void updateCodeInfoMap() {
		codeInfoMap = null;
		loadCodeInfoMap();
	}

	/**
	 * 获取->缓存001：（代码信息TIO_SYS_CODE_INFO）codeInfoMap< codeTypeId, List<SysCodeInfo> >
	 * 
	 * @return
	 */
	protected static Map getCodeInfoMap() {
		if (codeInfoMap == null) {
			loadCodeInfoMap();
		}
		return codeInfoMap;
	}

	/**
	 * 更新->缓存001：（代码信息TIO_SYS_CODE_INFO）codeInfoMap< codeTypeId, List<SysCodeInfo> >
	 * 
	 * @param codeTypeId
	 */
	public static void updateCodeInfoMap(String codeTypeId) {
		if (codeInfoMap == null) {
			loadCodeInfoMap();
		} else {
			CodeInfoService codeInfoService = SpringBeanFactory.getBean(CodeInfoService.BEAN_ID);
			codeInfoMap.putAll(codeInfoService.getCodeInfoMap(codeTypeId));
		}
	}

	/**
	 * 装载->缓存002：（角色对菜单的操作权限TIO_SYS_AUTH_OPER）authOperMenuMap< roleId, List<operId> > 装载->缓存002：（角色对功能的操作权限TIO_SYS_AUTH_OPER）authOperFuncMap< roleId, List<operId> >
	 */
	private static void loadAuthOperMap() {
		// 1)把菜单权限表数据装入内存（按roleId分类）
		if (authOperMenuMap == null || authOperFuncMap == null) {
			AuthOperService authOperService = SpringBeanFactory.getBean(AuthOperService.BEAN_ID);
			authOperMenuMap = authOperService.getAuthOperMap(null, "1");
			authOperFuncMap = authOperService.getAuthOperMap(null, "2");
		}
	}

	public static void updateAuthOperMenuMap() {
		authOperMenuMap = null;
		loadAuthOperMap();
	}

	public static void updateAuthOperFuncMap() {
		authOperFuncMap = null;
		loadAuthOperMap();
	}

	/**
	 * 获取->缓存002：（角色对菜单的操作权限TIO_SYS_AUTH_OPER）authOperMenuMap< roleId, List<operId> >
	 * 
	 * @param roleId
	 * @return
	 */
	protected static List getAuthOperMenu(String roleId) {
		if (authOperMenuMap == null) {
			loadAuthOperMap();
		}
		Object obj = authOperMenuMap.get(roleId);
		return obj != null ? (List) obj : null;
	}

	/**
	 * 获取->缓存002：（角色对功能的操作权限TIO_SYS_AUTH_OPER）authOperFuncMap< roleId, List<operId> >
	 * 
	 * @param roleId
	 * @return
	 */
	protected static List getAuthOperFunc(String roleId) {
		if (authOperFuncMap == null) {
			loadAuthOperMap();
		}
		Object obj = authOperFuncMap.get(roleId);
		return obj != null ? (List) obj : null;
	}

	/**
	 * 更新->缓存002：（角色对菜单的操作权限TIO_SYS_AUTH_OPER）authOperMenuMap< roleId, List<operId> > 更新->缓存002：（角色对功能的操作权限TIO_SYS_AUTH_OPER）authOperFuncMap< roleId, List<operId> >
	 * 
	 * @param roleId
	 */
	public static void updateAuthOperMap(String roleId) {
		if (authOperMenuMap == null) {
			loadAuthOperMap();
		} else {
			AuthOperService authOperService = SpringBeanFactory.getBean(AuthOperService.BEAN_ID);
			authOperMenuMap.putAll(authOperService.getAuthOperMap(roleId, "1"));
			authOperFuncMap.putAll(authOperService.getAuthOperMap(roleId, "2"));
		}
	}

	/**
	 * 装载->缓存003：（机构TIO_SYS_ORG）orgMap< id, SysOrg >
	 */
	private static void loadOrgMap() {
		// 2)把机构表装入内存
		if (orgMap == null) {
			OrgService orgService = SpringBeanFactory.getBean(OrgService.BEAN_ID);
			orgMap = orgService.getOrgMap();
		}
	}

	/**
	 * 获取->缓存003：（机构TIO_SYS_ORG）orgMap< id, SysOrg >
	 * 
	 * @return
	 */
	protected static Map getOrgMap() {
		if (orgMap == null) {
			loadOrgMap();
		}
		return orgMap;
	}

	/**
	 * 更新->缓存003：（机构TIO_SYS_ORG）orgMap< id, SysOrg >
	 */
	public static void updateOrgMap() {
		// 先置为空值,再重新载入
		orgMap = null;
		loadOrgMap();
	}

	/**
	 * 装载->缓存004：缓存 机构id及其的子机构id列表 allSubOrgMap< orgId, list<orgId> >
	 */
	private static void loadAllSubOrgMap() {
		if (allSubOrgMap == null) {
			allSubOrgMap = new HashMap();
			OrgService orgService = SpringBeanFactory.getBean(OrgService.BEAN_ID);
			List orgList = orgService.getOrgList();

			Iterator iterator = orgList.iterator();
			while (iterator.hasNext()) {
				TSysOrg tSysOrg = (TSysOrg) iterator.next();
				List list = new ArrayList();

				// 将该机构的下级机构 组织 到list中
				addChildOrgToList(tSysOrg.getOrgId(), list, orgList);

				// 将子机构的 list 组织到map中
				if (list.size() > 0) {
					allSubOrgMap.put(tSysOrg.getOrgId(), list);
				}
			}
		}
	}

	/**
	 * 辅助装载->缓存004：将当前 机构id 所有的子机构 写入 参数list中（为 loadAllSubOrgMap 方法调用）
	 * 
	 * @param orgId
	 *            机构id
	 * @param list
	 *            保存所有子机构机构id的list
	 * @param orgList
	 *            系统所有的机构list,做参数过滤用
	 */
	private static void addChildOrgToList(String orgId, List list, List orgList) {

		Iterator it = orgList.iterator();
		while (it.hasNext()) {
			TSysOrg tSysOrg = (TSysOrg) it.next();
			if (orgId.equals(tSysOrg.getParentOrgId())) {
				list.add(tSysOrg.getOrgId());
				addChildOrgToList(tSysOrg.getOrgId(), list, orgList);
			}
		}
	}

	/**
	 * 获取->缓存004：缓存 机构id及其的子机构id列表 allSubOrgMap< orgId, list<orgId> >
	 * 
	 * @param orgId
	 * @return
	 */
	public static List getAllSubOrg(String orgId) {
		if (allSubOrgMap == null) {
			loadAllSubOrgMap();
		}
		Object obj = allSubOrgMap.get(orgId);
		return obj != null ? (List) obj : null;
	}

	/**
	 * 更新所有 子机构 缓存
	 */
	public static void updateAllSubOrgMap() {
		allSubOrgMap = null;
		loadAllSubOrgMap();
	}

	/**
	 * 装载->缓存005：把参数表装入内存
	 */
	private static void loadConfigMap() {
		// 2)把参数表装入内存
		if (configMap == null) {
			ConfigService configService = SpringBeanFactory.getBean(ConfigService.BEAN_ID);
			configMap = configService.getConfigMap();
		}
	}

	/**
	 * 获取->缓存005：取得参数信息
	 * 
	 * @return 参数列表
	 */
	public static Map getConfigMap() {
		if (configMap == null) {
			loadConfigMap();
		}
		return configMap;
	}

	/**
	 * 更新->缓存005：有更新TIO_SYS_CONFIG表时，需重载数据
	 */
	public static void updateConfigMap() {
		// 先置为空值,再重新载入
		configMap = null;
		loadConfigMap();
	}
}
